package com.example.ParseXML;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class ParsePackage {
	DefinePackage pack;
	Document dom;
	ArrayList<DefineItemref> listItemref;
	ArrayList<DefineItem> listItem;

	public ParsePackage(String strPath) {
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {
			FileInputStream fos = new FileInputStream(strPath);
			// Using factory get an instance of document builder
			DocumentBuilder db = dbf.newDocumentBuilder();

			// parse using builder to get DOM representation of the XML file
			dom = db.parse(fos);

		} catch (ParserConfigurationException pce) {
			System.out.println("PCE: " + pce.getMessage());
		} catch (SAXException se) {
			System.out.println("SE: " + se.getMessage());
		} catch (IOException ioe) {
			System.out.println("IOE: " + ioe.getMessage());
		}
	}

	public DefinePackage getPackage() {
		pack = new DefinePackage();
		Element docEle = dom.getDocumentElement();

		pack.setXmlns(docEle.getAttribute("xmlns"));
		pack.setVersion(docEle.getAttribute("version"));
		pack.setXml_lang(docEle.getAttribute("xml:lang"));
		pack.setUnique_identifier(docEle.getAttribute("unique-identifier"));
		pack.setPrefix(docEle.getAttribute("prefix"));

		// Get metadata
		DefineMetadata metadata = new DefineMetadata();

		NodeList nlMetadata = docEle.getElementsByTagName("metadata");
		Element elMetadata = (Element) nlMetadata.item(0);
		metadata.setXmlns_dc(elMetadata.getAttribute("xmlns:dc"));

		if (!(elMetadata.getElementsByTagName("dc:title").getLength() == 0)) {
			NodeList nlTitle = elMetadata.getElementsByTagName("dc:title");
			Element elTitlt = (Element) nlTitle.item(0);
			metadata.setTitle(elTitlt.getTextContent());
		}

		if (!(elMetadata.getElementsByTagName("dc:creator").getLength() == 0)) {
			NodeList nlCreator = elMetadata.getElementsByTagName("dc:creator");
			Element elCreator = (Element) nlCreator.item(0);
			metadata.setCreator(elCreator.getTextContent());
		}
		if (!(elMetadata.getElementsByTagName("dc:language").getLength() == 0)) {
			NodeList nlLanguge = elMetadata.getElementsByTagName("dc:language");
			Element elLanguage = (Element) nlLanguge.item(0);
			metadata.setLanguage(elLanguage.getTextContent());
		}
		if (!(elMetadata.getElementsByTagName("dc:identifier").getLength() == 0)) {
			NodeList nlIdentifier = elMetadata
					.getElementsByTagName("dc:identifier");
			Element elIdentifier = (Element) nlIdentifier.item(0);
			metadata.setIdentifier(elIdentifier.getTextContent());
		}
		if (!(elMetadata.getElementsByTagName("dc:source").getLength() == 0)) {

			NodeList nlSource = elMetadata.getElementsByTagName("dc:source");
			Element elSource = (Element) nlSource.item(0);
			metadata.setSource(elSource.getTextContent());
		}
		if (!(elMetadata.getElementsByTagName("dc:date").getLength() == 0)) {

			NodeList nlDate = elMetadata.getElementsByTagName("dc:date");
			Element elDate = (Element) nlDate.item(0);
			metadata.setDate(elDate.getTextContent());
		}
		if (!(elMetadata.getElementsByTagName("dc:publisher").getLength() == 0)) {
			NodeList nlPublisher = elMetadata
					.getElementsByTagName("dc:publisher");
			Element elPublisher = (Element) nlPublisher.item(0);
			metadata.setPublisher(elPublisher.getTextContent());
		}
		if (!(elMetadata.getElementsByTagName("dc:rights").getLength() == 0)) {
			NodeList nlRights = elMetadata.getElementsByTagName("dc:rights");
			Element elRights = (Element) nlRights.item(0);
			metadata.setRight(elRights.getTextContent());
		}

		if (!(elMetadata.getElementsByTagName("dc:description").getLength() == 0)) {
			NodeList nlDescription = elMetadata
					.getElementsByTagName("dc:description");
			Element elDescription = (Element) nlDescription.item(0);
			metadata.setDescription(elDescription.getTextContent());
		}

		if (!(elMetadata.getElementsByTagName("dc:subject").getLength() == 0)) {
			NodeList nlSubject = elMetadata.getElementsByTagName("dc:subject");
			Element elSubject = (Element) nlSubject.item(0);
			metadata.setSubject(elSubject.getTextContent());
		}

		// Get meta element
		if (!(elMetadata.getElementsByTagName("meta").getLength() == 0)) {
			ArrayList<DefineMeta> listMeta = new ArrayList<DefineMeta>();
			NodeList nlMeta = elMetadata.getElementsByTagName("meta");
			for (int i = 0; i < nlMeta.getLength(); i++) {
				Element elMeta = (Element) nlMeta.item(i);
				DefineMeta meta = new DefineMeta();
				meta.setProperty(elMeta.getAttribute("property"));
				meta.setRefines(elMeta.getAttribute("refines"));
				meta.setValue(elMeta.getTextContent());
				listMeta.add(meta);
			}
			metadata.setMeta(listMeta);
		}

		// Get Link element
		if (!(elMetadata.getElementsByTagName("link").getLength() == 0)) {
			ArrayList<DefineLink> listLink = new ArrayList<DefineLink>();
			NodeList nlLink = elMetadata.getElementsByTagName("link");
			for (int i = 0; i < nlLink.getLength(); i++) {
				Element elLink = (Element) nlLink.item(i);
				DefineLink link = new DefineLink();
				link.setRefines(elLink.getAttribute("refines"));
				link.setRel(elLink.getAttribute("rel"));
				link.setHref(elLink.getAttribute("href"));
				listLink.add(link);
			}
			metadata.setLink(listLink);
		}
		pack.setMetadata(metadata);

		// Get manifest
		NodeList nlManifest = docEle.getElementsByTagName("manifest");
		Element elManifest = (Element) nlManifest.item(0);

		listItem = new ArrayList<DefineItem>();
		NodeList nlItem = elManifest.getElementsByTagName("item");
		for (int i = 0; i < nlItem.getLength(); i++) {
			Element elItem = (Element) nlItem.item(i);
			DefineItem item = new DefineItem();
			item.setId(elItem.getAttribute("id"));
			item.setProperties(elItem.getAttribute("properties"));
			item.setHref(elItem.getAttribute("href"));
			item.setMedia_type(elItem.getAttribute("media-type"));
			item.setMedia_overlay(elItem.getAttribute("media-overlay"));
			listItem.add(item);
		}
		pack.setItem(listItem);

		// Get Spine
		NodeList nlSpine = docEle.getElementsByTagName("spine");
		Element elSpine = (Element) nlSpine.item(0);

		listItemref = new ArrayList<DefineItemref>();
		NodeList nlItemref = elSpine.getElementsByTagName("itemref");
		for (int i = 0; i < nlItemref.getLength(); i++) {
			Element elItemref = (Element) nlItemref.item(i);
			DefineItemref itemref = new DefineItemref();
			itemref.setIdref(elItemref.getAttribute("idref"));
			itemref.setLinear(elItemref.getAttribute("linear"));
			listItemref.add(itemref);
		}
		pack.setItemref(listItemref);

		return pack;
	}

	public ArrayList<String> getTOC() {
		getPackage();
		ArrayList<String> result = new ArrayList<String>();
		for (int i = 0; i < listItemref.size(); i++) {
			String temp = listItemref.get(i).getIdref();
			// System.out.println(temp);
			for (int j = 0; j < listItem.size(); j++) {
				if (temp.equals(listItem.get(j).getId())) {
					result.add(listItem.get(j).getHref());
				}
			}
		}
		return result;
	}

	public DefineItem getItemById(String id) {
		getPackage();
		for (int i = 0; i < listItem.size(); i++) {
			if (listItem.get(i).getId().equals(id))
				return listItem.get(i);
		}
		return null;

	}
}
